import sys

import osTimer
import utime
import ntptime
import checkNet
from misc import Power
from usr.device import aht
from usr.device import light
from usr.WLAN import ESP8266
from machine import UART
import sim
from machine import ExtInt
from usr.dialog import Dialog
import usr.store as store
from usr.mainwindow import MainWindow
from usr.aboutwindow import AboutWindow
from queue import Queue
import usr.screen as Screen
from usr.modbus_service import ModbusService 
from usr.modbus_slave import ModbusSlave
import gc
import _thread
from umqtt import MQTTClient

gc.enable()
dialog = Dialog()

PROJECT_NAME = "Test"
PROJECT_VERSION = "1.0.0"

TIME_ZONE = 8
#消息
WM_TIMER1 = 1
WM_TIMER2 = 2
WM_KEY1_UP = 3
WM_KEY1_DOWM = 4
WM_KEY2_UP = 5
WM_KEY2_DOWM = 6

mainwin = MainWindow()
aboutwin = AboutWindow()
modbus = ModbusSlave()
modbus_service = ModbusService(modbus)

queue = Queue()
global key1_ext
global key2_ext
global wifi
global mqtt
checknet = checkNet.CheckNetwork(PROJECT_NAME, PROJECT_VERSION)
def mqtt_callback(topic, data):
    print(topic)
    print(data)

def init_mqtt():
    global mqtt
    #try:
    client_id = 'test123456'
    server = 'mqtts.heclouds.com'
    port = 1883
    user = 'w8MiLxx3uO'
    pwd = r"version=2018-10-31&res=products%2Fw8MiLxx3uO&et=4089078244&method=sha256&sign=kXj4xktZt3631GNQwTS%2FKOBzWY358%2Fy0ZnJ0TPwMn7k%3D"
    mqtt = MQTTClient(client_id, server, port, user, pwd, keepalive=300)
    mqtt.set_callback(mqtt_callback)
    mqtt.connect()
    mqtt.subscribe(b'$sys/w8MiLxx3uO/test123456/custome/up_reply')
    mqtt.publish(b'$sys/w8MiLxx3uO/test123456/custome/up', b'0103000000204412')

    '''except Exception as e:
        print('mqtt error')
        print(e)
        '''

def key1_handler(args):
    global key1_ext
    key1_ext.disable()
    io = args[0]
    tr = args[1]
    event = None
    if  tr == 0:
        event = 'up'
    else:
        event = 'down'
    if event == 'up':
        queue.put(WM_KEY1_UP)
        store.queue = queue.size()
    key1_ext.enable()

def key2_handler(args):
    global key2_ext
    key2_ext.disable()
    io = args[0]
    tr = args[1]
    event = None
    if  tr == 0:
        event = 'up'
    else:
        event = 'down'
    if event == 'up':
        queue.put(WM_KEY2_UP)
        store.queue = queue.size()
    key2_ext.enable()
#初始化输入
def init_input():
    global key1_ext
    global key2_ext
    key1_ext = ExtInt(ExtInt.GPIO13, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, key1_handler)
    key1_ext.enable()
    key2_ext = ExtInt(ExtInt.GPIO12, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, key2_handler)
    key2_ext.enable()

def wifi_callback(args):
    global wifi
    print(args)
    if 'connected' in args:
        print('WIFI connected')
        wifi.set_dns('114.114.114.114','8.8.8.8')
        wifi.set_default_NIC('172.16.1.2')
        sync_time()
    
def open_wifi():
    global wifi
    show_message('正在连接WIFI...')
    id = 'FAST8'
    pwd = '###qj200154***'
    wifi = ESP8266(UART.UART2, ESP8266.STA, wifi_callback)
    utime.sleep(1)
    wifi.station(id, pwd)
    '''ret = wifi.web_config(id, pwd)
    if ret != 0:
        print('Wifi web config failed')
        wifi.close()
        return 0
    '''
    utime.sleep(1)
    status = wifi.status()
    if status == 1:
        wifi.set_dns('114.114.114.114','8.8.8.8')
        wifi.set_default_NIC('172.16.1.2')
        utime.sleep(1)
        print(wifi.ipconfig())
        return 1
    
    utime.sleep(1)
    #print(wifi.version())
    return 0

def on_timer1(t):
    store.queue = queue.size()
    queue.put(WM_TIMER1)


def on_timer2(t):
    store.queue = queue.size()
    queue.put(WM_TIMER2)

#检测网络连接
def check_network():
    msg = "正在连接网络..."
    show_message(msg)
    status = sim.getStatus()
    if status == 1:
        return 1
    if status == 18:
        stagecode, subcode = checknet.wait_network_connected(2)
        if stagecode == 3 and subcode == 1:
            return 1
    #使用WIFI
    ret = open_wifi()
    if ret == 1:
        return 1
    return 0

def check_time():
    utime.setTimeZone(TIME_ZONE)
    try:
        if check_network() == 1:
            print("Sync time")
            sync_time()
    except Exception as err:
        show_message('校时失败', 2)

def sync_time():
    # 设置ntp服务
    ntptime.sethost('ntp.aliyun.com')

    # 同步ntp服务时间
    return ntptime.settime(TIME_ZONE)

def show_message(msg, delay = 0):
    dialog.show_info(msg)
    if delay > 0:
        utime.sleep(delay)


def measure():
    try:
        temp, humi = aht.measure()
        modbus.write_float(0x0000, temp)
        modbus.write_float(0x0002, humi)
        store.temp = "{0:>4.1f}".format(temp)
        store.humi = "{0:>4.1f}".format(humi)
        lv = Power. getVbatt()
        store.battery = '{:>4.1f}'.format(lv/1000)
    except Exception as err:
        print(err)
        # t.stop()
#初始化设备
def init_device():
    aht.init()

def handle_message(msg):
    if msg == WM_TIMER1:
        if mainwin.visible:
            mainwin.update()
    elif msg == WM_TIMER2:
        measure()
    elif msg == WM_KEY1_UP:
        if store.window == 'main':
            mainwin.close()
            aboutwin.show()
            store.window = 'about'
        else:
            mainwin.show()
            store.window = 'main'
    elif msg == WM_KEY2_UP:
        if store.screen == 1:
            Screen.close()
            store.screen = 0
        else:
            Screen.open()
            store.screen = 1
        #gc.collect()

def main_task():
    while True:
        try:
            #print('Fetch message')
            msg = queue.get()
            if msg is not None:
                handle_message(msg)
            #print('Ok')
            #utime.sleep_ms(20)
        except Exception as ex:
            print(ex)

def main():
    #校时
    check_time()

    init_device()
    init_input()
    #init_mqtt()

    mainwin.show()
    #先采集一次
    measure()
    mainwin.update()
    #定时任务
    
    timer1 = osTimer()
    timer1.start(10000, 1, on_timer1)
    timer2 = osTimer()
    timer2.start(5000, 1, on_timer2)
    
    #print("App started")
    #进入循环
    #loop()
    _thread.start_new_thread(main_task, ())
    modbus_service.start()


if __name__ == '__main__':
    main()